package edu.ucdavis.gwt.gis.client.dandd;

import com.google.gwt.dom.client.Style.Overflow;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.dom.client.MouseUpEvent;
import com.google.gwt.event.dom.client.MouseUpHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Widget;

/**
 * A movable container widgets are wrapped in while being dragged inside
 * the DragAndDropContainer
 * 
 * @author jrmerz
 */
public class Moveable extends Composite {
	
	private Widget widget = null;
	private EventPanel eventPanel = new EventPanel();
	private DragAndDropContainer ddContainer = null;
	private EventPanel contentPanel = null;
	
	private boolean delayMouseDown = false;
	private int offsetY = 0;
	private int startY = 0;
	
	/**
	 * Create a new moveable panel
	 * 
	 * @param w - widget to be wrapped
	 * @param ddc - parent container
	 */
	public Moveable(EventPanel w, DragAndDropContainer ddc) {
		contentPanel = w;
		eventPanel.add(w);
		eventPanel.setStyleName("Moveable");
		initWidget(eventPanel);
		
		widget = w;
		ddContainer = ddc;
		
		eventPanel.addMouseDownHandler(new MouseDownHandler(){
			@Override
			public void onMouseDown(MouseDownEvent event) {
				if( contentPanel.disabled() ) return;
				
				delayMouseDown = true;
				offsetY = event.getY();
				startY = event.getRelativeY(ddContainer.getElement());
				Timer t = new Timer() {
					@Override
					public void run() {
						mouseDown();
					}
				};
				t.schedule(200);
			}
		});
		
		eventPanel.addMouseUpHandler(new MouseUpHandler(){
			@Override
			public void onMouseUp(MouseUpEvent event) {
				if( contentPanel.disabled() ) return;
				
				delayMouseDown = false;
			}
		});
		
		getElement().getStyle().setOverflow(Overflow.VISIBLE);
		getElement().getStyle().setPosition(Position.RELATIVE);
	}
	
	/**
	 * get the top of the moveable
	 * 
	 * @return int
	 */
	public int getY() {
		return eventPanel.getAbsoluteTop();
	}
	
	/**
	 * get the wrapped widget
	 */
	public Widget getWidget() {
		return widget;
	}
	
	/**
	 * fire mouse down events
	 */
	private void mouseDown() {
		if( !delayMouseDown ) return;
		
		eventPanel.setWidth(eventPanel.getOffsetWidth()+"px");
		eventPanel.getElement().getStyle().setTop(startY-offsetY, Unit.PX);
		
		ddContainer.setSelected(Moveable.this);
		eventPanel.addStyleDependentName("selected");
	}
	
	/**
	 * Fire mouse up events
	 */
	public void mouseUp() {
		delayMouseDown = false;
		
		eventPanel.setWidth("auto");
		eventPanel.removeStyleDependentName("selected");
		eventPanel.getElement().getStyle().setTop(0, Unit.PX);
		
		ddContainer.setSelected(null);
	}
	
	/**
	 * move the panel
	 * 
	 * @param pos - vertical position to move to
	 */
	public void move(int pos) {
		//int pos = y - getAbsoluteTop();
		eventPanel.getElement().getStyle().setTop(pos-offsetY, Unit.PX);
	}
	
}
